#define _CRT_SECURE_NO_WARNINGS 1


//https://leetcode.cn/problems/implement-queue-using-stacks/submissions/

typedef int STDataType;

typedef struct Stack
{
	STDataType* a;
	int capacity;
	int top;

}ST;

void StackInit(ST* ps);
void StackDestroy(ST* ps);
void StackPush(ST* ps, STDataType x);
void StackPop(ST* ps);

STDataType StackTop(ST* ps);
bool StackEmpty(ST* ps);


int StackSize(ST* ps);
void StackPrintf(ST* ps);


void StackInit(ST* ps)
{
	ps->a = (STDataType*)malloc(sizeof(STDataType) * 4);
	if (ps->a == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}
	ps->capacity = 4;
	ps->top = 0;
}
void StackDestroy(ST* ps)
{
	assert(ps->a);
	free(ps->a);
	ps->a = NULL;
	ps->capacity = ps->top = 0;
}
void StackPush(ST* ps, STDataType x)
{
	assert(ps->a);
	if (ps->top == ps->capacity)
	{
		ps->a = (STDataType*)realloc(ps->a, sizeof(STDataType) * 2 * ps->capacity);
		ps->capacity = ps->capacity * 2;
	}
	ps->a[ps->top] = x;
	ps->top++;

}
void StackPop(ST* ps)
{
	assert(ps->a);
	assert(ps->top > 0);
	ps->top--;
}

STDataType StackTop(ST* ps)
{
	assert(ps->a);
	assert(ps->top >= 0);

	return ps->a[ps->top - 1];
}
bool StackEmpty(ST* ps)
{
	return ps->top == 0;
}


int StackSize(ST* ps)
{
	return ps->top;
}

void StackPrintf(ST* ps)
{
	int i = ps->top;
	int j = 0;
	while (i-- > 0)
	{
		printf("%d ", ps->a[j++]);

	}
	printf("\n");
}


typedef struct {
	ST pushst;
	ST popst;

} MyQueue;

int myQueuePeek(MyQueue* obj);
bool myQueueEmpty(MyQueue* obj);

MyQueue* myQueueCreate() {
	MyQueue* pq = (MyQueue*)malloc(sizeof(MyQueue));
	StackInit(&pq->pushst);
	StackInit(&pq->popst);

	return pq;
}

void myQueuePush(MyQueue* obj, int x) {
	assert(obj);

	StackPush(&obj->pushst, x);

}

int myQueuePop(MyQueue* obj) {
	assert(obj);
	assert(!myQueueEmpty(obj));

	int peek = myQueuePeek(obj);
	StackPop(&obj->popst);
	return peek;

}

int myQueuePeek(MyQueue* obj) {
	assert(obj);
	assert(!myQueueEmpty(obj));

	if (StackEmpty(&obj->popst))
	{
		while (!StackEmpty(&obj->pushst))
		{
			StackPush(&obj->popst, StackTop(&obj->pushst));
			StackPop(&obj->pushst);
		}
	}
	return StackTop(&obj->popst);
}

bool myQueueEmpty(MyQueue* obj) {
	assert(obj);
	return StackEmpty(&obj->pushst) && StackEmpty(&obj->popst);

}

void myQueueFree(MyQueue* obj) {

	assert(obj);
	StackEmpty(&obj->pushst);
	StackEmpty(&obj->popst);
	free(obj);


}

/**
 * Your MyQueue struct will be instantiated and called as such:
 * MyQueue* obj = myQueueCreate();
 * myQueuePush(obj, x);

 * int param_2 = myQueuePop(obj);

 * int param_3 = myQueuePeek(obj);

 * bool param_4 = myQueueEmpty(obj);

 * myQueueFree(obj);
*/